var wxView = require('wxview.js');
var wxTouch = require('wxtouch.js');
var util = require('../utils/util.js');
var app = getApp();
(function() {
    var list = wxView.createWXView();
    list.initList = function(page, winWidth, winHeight, renderParam) {
        this.items = [];
        this.count = 0;
        this.page = page;
        this.winWidth = winWidth;
        this.winHeight = winHeight;
        this.width = winWidth;
        this.height = 0;
        this.setWH(winWidth, 0);
        var s = this;

        this.renderParam = renderParam;
        this.currentAction = 0;

        this.y = 0;
        this.isShade = false;

        this.resetMoveStates();

        var s = this;
        // this.setTouchendMovecb(
        //     function (e, type, args) {
        //         return;
        //         if (s.y > 0) {
        //             var pct = s.y / app.CREATE_ITEM_THRESHOLD;
        //             var r = Math.max(0, (1 - pct) * 90);
        //             s.topItem.rotateX(r);
        //             s.renderPage();
        //         }
        //     }
        // )
    };

    list.setInput = function(input) {
        this.input = input;
    };

    list.setLastPos = function(lastPos) {
        this.lastPos = lastPos;
    };

    list.setSortItem = function(sortItem) {
        this.sortItem = sortItem;
    };

    list.resetMoveStates = function() {
        this._longPullUp = false;
        this._pastLongPullUpThreshold = false;
        this._pullDown = false;
        this._longPullDown = false;
        this._pastPullDownThreshold = false;
    };

    list.renderPage = function() {
        this.page.render();
    };

    list.renderListNoPaint = function(isMove) {
        var dataList = [];
        for (var i = 0; i < this.items.length; i++) {
            var data = this.itemToRenderData(this.items[i], isMove);
            dataList.push(data);
        }
        var renderData = this.page.getRenderData();
        renderData[this.renderParam] = dataList;
    };

    list.renderList = function(isMove) {
        this.renderListNoPaint(isMove);
        console.log(this.page.getRenderData());
        this.renderPage();
    };

    list.loadData = function(dataList) {
        this.count = 0;
        this.height = 0;
        this.items = [];
        this.dataList = dataList;
        for (var i = 0; i < dataList.length; i++) {
            var item = this.createItem(dataList[i]);
            this.addItem(item);
        }
        this.updateBound(true);
        for (var i = 0; i < this.items.length; i++) {
            this.items[i].calColor(this.count);
        }
        this.renderList();
    };

    list.resort = function() {
        function sortfunc(a, b) {
            return a.getOrder() - b.getOrder();
        }
        this.items.sort(sortfunc);
    };

    list.resortData = function() {
        function sortfunc(a, b) {
            return a.order - b.order;
        }
        this.dataList.sort(sortfunc);
    };

    list.resetItemIndex = function() {
        var i = this.items.length;
        while (i--) {
            this.items[i].index = i;
        }
    };

    list.addItem = function(item) {
        this.items.push(item);
        item.list = this;
        item.index = this.items.length - 1;
        if (!item.done) {
            this.count++;
        } 
        this.height += item.height;  
    };

    list.updateColor = function() {
        var i = this.items.length;
        while (i--) {
            this.items[i].updateColor(this.count);
        }
    };

    list.resetPosition = function() {
        var i = this.items.length;
        while (i--) {
            this.items[i].moveY(0);
        }
    };

    list.initPosition = function() {
        var y = 0;
        for (var i = 0; i < this.dataList.length; i++) {
            var data = this.dataList[i];
            var item = this.getItemById(data.id);
            item.moveY(y);
            y += item.height;
        }
    };

    list.updatePosition = function() {
        var y = 0;
        for (var i = 0; i < this.dataList.length; i++) {
            var data = this.dataList[i];
            var item = this.getItemById(data.id);
            item.updatePosition(y);
            y += item.height;
        }
    };

    list.changeItemPostion = function(start, end, y) {
        start = Math.max(0, start);
        end = Math.min(this.items.length, end);
        for (var i = start; i < end; i++) {
            var item = this.items[i];
            item.changeY(y);
        }
    };

    list.updateBound = function(noMove) {
        var upBound = Math.min(0, this.winHeight - (this.height + app.CREATE_ITEM_THRESHOLD));
        console.log(upBound);
        console.log(this.height);
        this.setBound(upBound, 0);

        if (this.y < this.upBound && !noMove) {
            this.smoothMoveY(this.upBound);
        }
    };

    list.collapseAt = function(at, target) {
        var items = this.items,
        i = items.length, item;
        var height = target.height;
        while (i--) {
            item = items[i];
            if (item === target) {
                continue;
            }
            if (!item.done) {
                item.updateColor(this.count);
            }
            if (target.deleted) {
                if (item.getOrder() > at) {
                    item.minusOrder();
                    item.updatePosition(item.y - height);
                }
            }
            else {
                if (!item.done && item.getOrder() > at) {
                    item.minusOrder();
                    item.updatePosition(item.y - height);
                }
            }      
        };
        this.renderPage();
    };

    list.getItemById = function(id) {
        for (var i = 0; i < this.items.length; i++) {
            if (this.items[i].id === id) {
                return this.items[i];
            }
        }
        return null;
    };

    list.getItemIndex = function(item) {
        var i = this.items.length;
        while (i--) {
            if (this.items[i] === item) {
                return i;
            }
        }
        return -1;
    };

    list.deleteItemById = function(id) {
        var i = this.items.length, item;
        while (i--) {
            item = this.items[i];
            if (item.id === id) {
                this.items.splice(i, 1);
                return;
            }
        }
    };

    list.calUpHeight = function(at) {
        var height = 0;
        for (var i = 0; i < this.items.length; i++) {
            if (this.items[i].getOrder() < at) {
                height += this.items[i].height;
            }
        }
        return height;
    };

    list.setOpacity = function(o) {
        this.opacity = o;
        var sindex = this.animationParam;
        var animation = wx.createAnimation({duration:300, timingFunction:'ease-in-out'});
        animation.opacity(o).step();
        var renderData = this.page.getRenderData();
        renderData[sindex] = animation.export();
    };

    list.shade = function(start) {
        if (this.isShade) {
            return;
        } 
        this.isShade = true;
        for (var i = 0; i < this.items.length; i++) {
            if (this.items[i].getOrder() >= start) {
                this.items[i].setOpacity(0.15);
            }
        }
    };

    list.unShade = function() {
        if (!this.isShade) {
            return;
        }
        this.isShade = false;
        var i = this.items.length;
        while (i--) {
          if (!this.items[i].deleted) {
              this.items[i].setOpacity(1);
          }
      }
    };

        
    list.onlongtap = function(e, input) {
        if (this.currentAction === util.TOUCH_ACTION_LIST) {
            return;
        }
        if (this.currentItem) {
            this.currentAction = util.TOUCH_ACTION_SORT;
            this.currentItem.sortstart();
            this.isSorting = true;
        }
    };


    list.touchstart = function(e, input) {
        if (this.page.isEditing) {
            return;
        }
        if (this.isMove) {
            this.movingTouch = true;
            this.currentAction = util.TOUCH_ACTION_LIST;
        }
        this.ontouchstart(e);
        var item = this.getItemById(e.target.id);
        if (item) {
            item.ontouchstart();
            this.currentItem = item;
        }
        else {
            this.currentItem = null;
        }
    };

    list.touchmove = function(e, input) {
        if (this.page.isEditing) {
            return;
        }
        this._isMoved = true;
        if (this.currentAction === util.TOUCH_ACTION_NONE) {
            if (wxTouch.isMoveHorizontal(input) && this.currentItem) {
                this.currentAction = util.TOUCH_ACTION_ITEM;
            }
            else {
                this.currentAction = util.TOUCH_ACTION_LIST;
            }
        }
        if (this.currentAction === util.TOUCH_ACTION_ITEM) {
            this.currentItem.touchmove(input.deltaX);
        }
        else if (this.currentAction === util.TOUCH_ACTION_SORT) {
            this.currentItem.sortmove(e, input);
        } 
        else {
            this.ontouchmove(e, input.deltaY);
        }
    };

    list.touchend = function(e, input) {
        if (this.page.isEditing) {
            return;
        }

        if (this.currentAction === util.TOUCH_ACTION_SORT) {
            this.currentItem.sortend();
        }
        else if (this.currentAction === util.TOUCH_ACTION_ITEM) {
            if (this._isMoved) {
                this.currentItem.touchend();
            }   
        }
        else {
            if (this._isMoved) {
                this.ontouchend(e, input.speedY);
            }  
        }

        this._isMoved = false;
        this.currentAction = util.TOUCH_ACTION_NONE;
        this.currentItem = null;

    };

    list.onItemHeightChange = function(at, heightChange) {
        var i = this.items.length;
        while (i--) {
            if (this.items[i].getOrder() > at) {
                this.items[i].changeY(heightChange);
            }
        }
        this.height += heightChange;
        this.updateBound(true);
    };

    list.smoothMoveItemDown = function(at) {
        var i = this.items.length;
        while (i--) {
            if (this.items[i].getOrder() > at) {
                this.items[i].smoothChangeY(app.ITEM_HEIGHT);
            }
        }
    };

    list.onPullDown = function() {
        this.onEditStart(true, true);
    };

    list.pullDown = function() {
        if (this._pullDown) {
            return;
        }
        this._pullDown = true;
        this.topItem.show();
        this.topItem.setText(this.pullDownCreateText);
    };

    list.unPullDown = function() {
        if (!this._pullDown) {
            return;
        }
        this._pullDown = false;
        this.topItem.hide();
    };

    list.pastPullDownThreshold = function() {
        if (this._pastPullDownThreshold) {
            return;
        }
        this._pastPullDownThreshold = true;
        this.topItem.setText(this.releaseCreateText);
        this.topItem.rotateX(0);
        this.topItem.setOpacity(1);
    };

    list.unPastPullDownThreshold = function() {
        if (this._pastPullDownThreshold) {
            this._pastPullDownThreshold = false;
            this.topItem.setText(this.pullDownCreateText);
        }
        var pct = this.y / app.CREATE_ITEM_THRESHOLD;
        var r = Math.max(0, (1 - pct) * 90);
        var opacity = pct / 2 + .5;
        this.topItem.rotateX(r);
        this.topItem.setOpacity(opacity);
    };

    list.activateInput = function(text) {
        var input = this.input;
        input.show();
        input.setFocus(true);
        if (text) {
            input.setText(text);
        }
    };

    list.unActivateInput = function() {
        var input = this.input;
        input.hide();
        input.setFocus(false);
        input.setText('');
    };

    list.setInputText = function(text) {
        this.input.setText(text);
    };

    list.onlinechange = function(e) {
        if (!this.page.isEditing || !this.startEditing) {
            return;
        }
        this.currentEditItem.setLineCount(e.detail.lineCount);
        this.renderPage();
        this.lineCount = e.detail.lineCount;
    };

    list.onEditStart = function(isNew, isTop, item) {
        this.lineCount = 1;
        this.page.isEditing = true;
        this.isEditNew = isNew;
        this.isEditTop = isTop;

        if (isNew) {
            this.onCreateStart(isTop);
        }
        else {
            this.beforeEditPos = this.y;
            this.currentEditItem = item;
            this.activateInput();
            this.shade(item.getOrder() + 1);
            var s = this;
            function callback() {
                s.currentEditItem.hideText();
                s.setInputText(item.getText());
                s.startEditing = true;
                s.renderPage();
            }
            this.smoothMoveY(-item.y, callback);
        }
    };

    list.onCreateStart = function(isTop) {
        if (isTop) {
            this.topItem.setText('');
            this.activateInput();
            this.renderPage();
            var s = this;
            function callback() {
                s.topItem.hide();
                s.currentEditItem.setHeight(app.ITEM_HEIGHT);
                s.startEditing = true;
                s.onItemHeightChange(0, app.ITEM_HEIGHT);
                s.moveY(0);
            }
            this.beforeEditPos = 0;
            this.currentEditItem = this.createItemAt(0);
            this.shade(1);
            this.smoothMoveY(app.ITEM_HEIGHT, callback);
            this.save();
        }
        else {
            var height = this.calUpHeight(this.count);
            this.beforeEditPos = this.y;
            var s = this;
            function callback() {
                s.activateInput();
                s.currentEditItem = s.createItemAt(s.count);
                s.shade(s.count);
                s.smoothMoveY(-height, function() {
                    s.currentEditItem.setHeight(app.ITEM_HEIGHT);
                    s.height += app.ITEM_HEIGHT;
                    s.updateBound(true);

                    s.startEditing = true;
                    s.bottomItem.hide();
                    s.bottomItem.smoothRotateX(-90);
                    s.renderPage();
                });
                s.save();
            }
            this.bottomItem.setTop(height);
            var color = this.itemcolorCal.calItemColor(this.count, this.count+1);
            this.bottomItem.setColor(color);
            this.bottomItem.show();
            this.renderPage();
            this.smoothMoveItemDown(this.count - 1);
            this.bottomItem.smoothRotateX(0, callback);
            this.renderPage();
        }
    }

    list.onEditDone = function(value) {
        this.startEditing = false;
        this.unShade();
        this.unActivateInput();
        this.renderPage();
        
        value = value.trim();
        if (value === '') {
            if (this.beforeEditPos !== this.y) {
                var s = this;
                this.smoothMoveY(this.beforeEditPos, function() {
                s.currentEditItem.del();
                });
            }
            else {
                this.currentEditItem.del();
            }
        }
        else {
            this.currentEditItem.setText(value, this.lineCount);
            this.currentEditItem.showText();
            this.renderPage();
            if (this.beforeEditPos !== this.y) {
                this.smoothMoveY(this.beforeEditPos);
            }
            this.save();
        }
    };

    list.logList = function() {
        var i = this.items.length;
        while (i--) {
            //console.log(this.items[i]);
            console.log(this.items[i].data);
        }
    };

    list.createItemAt = function(order) {
        var data = this.createNewData(order);
        this.dataList.splice(order, 0, data);
        this.count++;

        var newItem = this.createItem(data);
        newItem.height = 0;
        var pos = this.calUpHeight(order);
        newItem.setY(pos);
        newItem.calColor(this.count); 

        for (var i = 0; i < this.items.length; i++) {
            var item = this.items[i];
            if (item.getOrder() >= order) {
                item.plusOrder();
            }
            item.calColor(this.count);
        }
        this.items.push(newItem);
        this.resort();

        this.renderList(true);
        this.resetItemIndex();

        if (typeof this.updateCount === 'function') {
            this.updateCount();
        }

        return newItem;
    };

    list.sortmove = function(dir, item) {
        var s = this,
        dy  = dir * app.ITEM_HEIGHT;
        s.sortMoving = true;
        loop();
        function loop () {
            if (!s.sortMoving) {
               return;
            }
            var cty = Math.max(s.upBound, Math.min(0, s.y + dy));
            s.checkSwap(item);
            s.lineMoveY(cty);
            setTimeout(loop, 280);
            s.renderPage();
        }
    };

    list.checkSwap = function(target) {
        var targetSY = this.sortItem.y;
        var targetSBottom = targetSY +  + target.height;
        var i = this.items.length;
        while (i--) {
            var item = this.items[i];
            if (item === target) {
                continue;
            }
            var sy = item.y + this.y,
                height = item.height;
            var sbottom = sy + height;
            if (item.getOrder() < target.getOrder()) {
                if ((targetSY - sy) < (item.height / 2)) {
                    item.smoothMoveY(item.y + target.height);
                    item.plusOrder();
                    target.minusOrder();
                }
            }
            else {
                if ((sbottom - targetSBottom) < (item.height / 2)) {
                    item.smoothMoveY(item.y - target.height);
                    item.minusOrder();
                    target.plusOrder();
                }
            }
        }
        this.renderPage();
    };

    function createList() {
        return Object.create(list);
    };

    module.exports = {createList: createList};

})();